package com.github.wxiaoqi.security.crm.core.biz;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.github.pagehelper.util.StringUtil;
import com.github.wxiaoqi.security.auth.common.util.SnowFlake;
import com.github.wxiaoqi.security.common.crm.request.IntoAccountRequest;
import com.github.wxiaoqi.security.common.enums.AccountStateEnums;
import com.github.wxiaoqi.security.common.enums.CustomerTypeEnums;
import com.github.wxiaoqi.security.common.enums.InOutFlagEnums;
import com.github.wxiaoqi.security.common.msg.ResponseCode;
import com.github.wxiaoqi.security.common.util.EntityUtils;
import com.github.wxiaoqi.security.common.util.MD5;
import com.github.wxiaoqi.security.crm.core.entity.MerchantAccount;
import com.github.wxiaoqi.security.crm.core.entity.MerchantAccountJournal;
import com.github.wxiaoqi.security.crm.core.entity.PersonalAccount;
import com.github.wxiaoqi.security.crm.core.entity.PersonalAccountJournal;
import com.github.wxiaoqi.security.crm.core.entity.PersonalBase;
import com.github.wxiaoqi.security.crm.core.entity.PersonalBilling;
import com.github.wxiaoqi.security.crm.core.entity.PlatformAccoutConfig;
import com.github.wxiaoqi.security.crm.core.mapper.MerchantAccountJournalMapper;
import com.github.wxiaoqi.security.crm.core.mapper.MerchantAccountMapper;
import com.github.wxiaoqi.security.crm.core.mapper.PersonalAccountJournalMapper;
import com.github.wxiaoqi.security.crm.core.mapper.PersonalAccountMapper;
import com.github.wxiaoqi.security.crm.core.mapper.PersonalBaseMapper;
import com.github.wxiaoqi.security.crm.core.mapper.PersonalBillingMapper;
import com.github.wxiaoqi.security.crm.core.mapper.PlatformAccoutConfigMapper;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;

/**
 * 入账相关的操作
 */
@Slf4j
@Transactional(rollbackFor = Exception.class)
@Service
public class CommonIntoAccountBiz {

	@Value("${bountyHunter.balanceSaltValue}")
	private String balanceSaltValue;
	@Autowired
	private MerchantAccountMapper merAccountMapper;
	@Autowired
	private PersonalAccountMapper personalAccountMapper;
	@Autowired
	private PersonalAccountJournalMapper personalAccountJournalMapper;
	@Autowired
	private PersonalBaseMapper personalBaseMapper;
	@Autowired
	private MerchantAccountJournalMapper merchantAccountJournalMapper;
	@Autowired
	private PlatformAccoutConfigMapper platformAccoutConfigMapper;
	/**
	 * 个人或者商户入账相关的接口: 
	 * 若是商户账户： 
	 * 1、商户账号入账 
	 * 2、新增商户账户流水记录
	 * 若是个人账户： 
	 * 1、个人账户入账
	 * 2、新增个人账户流水记录
	 */
	public Map<String, Object> intoAccount(IntoAccountRequest intoAccountRequest) {
		log.info("个人或者商户入账相关的接口 请求参数：{}" + EntityUtils.beanToMap(intoAccountRequest));
		Map<String, Object> response = new HashMap<String, Object>();
		if (intoAccountRequest.getCustomerType().equals(CustomerTypeEnums.mer_user.getCode())) {
			MerchantAccount queryAccount = new MerchantAccount();
			queryAccount.setPlatformId(intoAccountRequest.getPlatformId());
			queryAccount.setMerchantId(intoAccountRequest.getMerchantId());
			queryAccount.setMerchantType(intoAccountRequest.getMerchantType());
			queryAccount.setAccountType(intoAccountRequest.getAccountType());
			MerchantAccount merchantAccount = merAccountMapper.selectOne(queryAccount);
			String accountId = "";
			if (null == merchantAccount) {// 商户账号还未开户
				/**
				 * 商户账号开通
				 */
				PlatformAccoutConfig queryaccoutConfig=new PlatformAccoutConfig();
				queryaccoutConfig.setPlatformId(intoAccountRequest.getPlatformId());
				queryaccoutConfig.setCustomerType(intoAccountRequest.getMerchantType());
				queryaccoutConfig.setAccountType(intoAccountRequest.getAccountType());
				PlatformAccoutConfig accoutConfig =platformAccoutConfigMapper.selectOne(queryaccoutConfig);
				if(null==accoutConfig){//平台支持的账户类型不存在 就没法开户
					response.put("code", ResponseCode.PLAT_ACC_TYPE_NOT_EXIST.getCode());
					response.put("msg", ResponseCode.PLAT_ACC_TYPE_NOT_EXIST.getMessage());
					log.info("个人或者商户入账相关的接口-返回参数。。。。。。{}", response);
					return response;
				}
				MerchantAccount newAccount = new MerchantAccount();
				accountId = String.valueOf(SnowFlake.getId());
				newAccount.setAccountId(accountId);
				newAccount.setPlatformId(intoAccountRequest.getPlatformId());
				newAccount.setMerchantId(intoAccountRequest.getMerchantId());
				newAccount.setMerchantType(intoAccountRequest.getMerchantType());
				newAccount.setAccountType(intoAccountRequest.getAccountType());
				newAccount.setCcy("CNY");
				newAccount.setFreezeBalance(BigDecimal.ZERO);
				newAccount.setAccountBalance(new BigDecimal(intoAccountRequest.getIntoAccAmt()));
				newAccount.setCheckSum(MD5.sign(intoAccountRequest.getIntoAccAmt().toString(), balanceSaltValue, "utf-8"));
				newAccount.setStatus(AccountStateEnums.normal.getCode());
				newAccount.setCreateTime(new Date());
				merAccountMapper.insertSelective(newAccount);
			}else{
				if (null != merchantAccount && AccountStateEnums.normal.getCode().equals(merchantAccount.getStatus())) {
					if (!MD5.sign(merchantAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8").equals(merchantAccount.getCheckSum())) {
						response.put("code", ResponseCode.MER_ACC_BALANCE_NOT_MATE.getCode());
						response.put("msg", ResponseCode.MER_ACC_BALANCE_NOT_MATE.getMessage());
						log.info("入账（第三方支付）返回参数。。。。。。{}", response);
						return response;
					}
					merchantAccount.setAccountBalance(merchantAccount.getAccountBalance().add(new BigDecimal(intoAccountRequest.getIntoAccAmt())));
					merchantAccount.setCheckSum(MD5.sign(merchantAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8"));
					merAccountMapper.updateByPrimaryKeySelective(merchantAccount);
				} else {
					response.put("code", ResponseCode.MER_ACC_FREEZE.getCode());
					response.put("msg", ResponseCode.MER_ACC_FREEZE.getMessage());
					log.info("个人或者商户入账相关的接口 返回参数。。。。。。{}", response);
					return response;
				}
				if (StringUtils.isEmpty(accountId)) {
					accountId = merchantAccount.getAccountId();
				}
			}
			MerchantAccountJournal merAccountJournal = new MerchantAccountJournal();
			merAccountJournal.setJournalId(String.valueOf(SnowFlake.getId()));
			merAccountJournal.setPlatformId(intoAccountRequest.getPlatformId());
			merAccountJournal.setMerchantId(intoAccountRequest.getMerchantId());
			merAccountJournal.setAccountId(accountId);
			merAccountJournal.setAccountType(intoAccountRequest.getAccountType());
			merAccountJournal.setOrderNo(intoAccountRequest.getOrderNo());
			merAccountJournal.setInOutFlag(InOutFlagEnums.in.getCode());
			merAccountJournal.setTradeAmt(new BigDecimal(intoAccountRequest.getIntoAccAmt()));
			merAccountJournal.setTradeType(intoAccountRequest.getTradeType());
			merAccountJournal.setCreateTime(new Date());
			merchantAccountJournalMapper.insertSelective(merAccountJournal);
			response.put("code", ResponseCode.OK.getCode());
			response.put("msg", ResponseCode.OK.getMessage());
		}
		
		if (intoAccountRequest.getCustomerType().equals(CustomerTypeEnums.per_user.getCode())) {
			PersonalBase base = new PersonalBase();
			base.setPersonalId(intoAccountRequest.getPersonalId());
			PersonalBase reult = personalBaseMapper.selectOne(base);
			if (null == reult) {
				log.info("个人或者商户入账相关的接口 返回参数。。。。。。个人客户信息不存在");
				response.put("code", ResponseCode.PER_NOTEXIST.getCode());
				response.put("msg", ResponseCode.PER_NOTEXIST.getMessage());
				return response;
			}
			String perAccountId = "";
			PersonalAccount queryPerAccountparam=new PersonalAccount();
			queryPerAccountparam.setPlatformId(intoAccountRequest.getPlatformId());
			queryPerAccountparam.setPersonalId(intoAccountRequest.getPersonalId());
			queryPerAccountparam.setAccountType(intoAccountRequest.getAccountType());
			PersonalAccount personalAccount=personalAccountMapper.selectOne(queryPerAccountparam);
			String accountType = null;
			if(null==personalAccount){
				PlatformAccoutConfig queryaccoutConfig=new PlatformAccoutConfig();
				queryaccoutConfig.setPlatformId(intoAccountRequest.getPlatformId());
				queryaccoutConfig.setCustomerType(intoAccountRequest.getMerchantType());
				queryaccoutConfig.setAccountType(intoAccountRequest.getAccountType());
				PlatformAccoutConfig accoutConfig =platformAccoutConfigMapper.selectOne(queryaccoutConfig);
				if(null==accoutConfig){//平台支持的账户类型不存在 就没法开户
					response.put("code", ResponseCode.PLAT_ACC_TYPE_NOT_EXIST.getCode());
					response.put("msg", ResponseCode.PLAT_ACC_TYPE_NOT_EXIST.getMessage());
					log.info("个人或者商户入账相关的接口-返回参数。。。。。。{}", response);
					return response;
				}
				PersonalAccount newPerAcc= new PersonalAccount();
				perAccountId = String.valueOf(SnowFlake.getId());
				newPerAcc.setAccountId(perAccountId);
				newPerAcc.setPlatformId(intoAccountRequest.getPlatformId());
				newPerAcc.setPersonalId(intoAccountRequest.getPersonalId());
				newPerAcc.setAccountType(intoAccountRequest.getAccountType());
				newPerAcc.setCcy("CNY");
				newPerAcc.setAccountBalance(new BigDecimal(intoAccountRequest.getIntoAccAmt()));
				newPerAcc.setCheckSum(MD5.sign(intoAccountRequest.getIntoAccAmt().toString(), balanceSaltValue, "utf-8"));
				newPerAcc.setFreezeBalance(BigDecimal.ZERO);
				newPerAcc.setStatus(AccountStateEnums.normal.getCode());
				newPerAcc.setCreateTime(new Date());
				personalAccountMapper.insertSelective(newPerAcc);
				accountType = intoAccountRequest.getAccountType();
			}else{
				if (null != personalAccount && AccountStateEnums.normal.getCode().equals(personalAccount.getStatus())) {
					if (!MD5.sign(personalAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8").equals(personalAccount.getCheckSum())) {
						response.put("code", ResponseCode.PER_ACC_BALANCE_NOT_MATE.getCode());
						response.put("msg", ResponseCode.PER_ACC_BALANCE_NOT_MATE.getMessage());
						log.info("入账（第三方支付）返回参数。。。。。。{}", response);
						return response;
					}
					personalAccount.setAccountBalance(personalAccount.getAccountBalance().add(new BigDecimal(intoAccountRequest.getIntoAccAmt())));
					personalAccount.setCheckSum(MD5.sign(personalAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8"));
					personalAccountMapper.updateByPrimaryKeySelective(personalAccount);
				} else {
					response.put("code", ResponseCode.PER_ACC_FREEZE.getCode());
					response.put("msg", ResponseCode.PER_ACC_FREEZE.getMessage());
					log.info("个人或者商户入账相关的接口 返回参数。。。。。。{}", response);
					return response;
				}
				if (StringUtils.isEmpty(perAccountId)) {
					perAccountId = personalAccount.getAccountId();
				}
				accountType = personalAccount.getAccountType();
			}
			PersonalAccountJournal personalAccountJournal=new PersonalAccountJournal();
			personalAccountJournal.setJournalId(String.valueOf(SnowFlake.getId()));
			personalAccountJournal.setPlatformId(intoAccountRequest.getPlatformId());
			personalAccountJournal.setPersonalId(intoAccountRequest.getPersonalId());
			personalAccountJournal.setAccountId(perAccountId);
			personalAccountJournal.setAccountType(accountType);
			personalAccountJournal.setOrderNo(intoAccountRequest.getOrderNo());
			personalAccountJournal.setInOutFlag(InOutFlagEnums.in.getCode());//来往标志  1：来账   2：往账
			personalAccountJournal.setTradeAmt(new BigDecimal(intoAccountRequest.getIntoAccAmt()));
			personalAccountJournal.setTradeType(intoAccountRequest.getTradeType());//交易类型（支付:01，退款:02，提现:03，充值:04）
			personalAccountJournal.setCreateTime(new Date());
			personalAccountJournalMapper.insertSelective(personalAccountJournal);
			response.put("code", ResponseCode.OK.getCode());
			response.put("msg", ResponseCode.OK.getMessage());
		}
		return response;
	}


}
